package com.zoke.support.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;

import com.zoke.support.base.BaseActivity;

/**
 * 文件工具类
 * 
 * @author JackWu
 * @version
 * @date 2014-11-19
 * @_QQ_ 651319154
 */
public class FileUtil {
	private FileUtil() {
	}

	private static final int BUFFER_SIZE = 1024 * 1024; // 1M Byte

	/**
	 * 将文件转换为base64以后的字符串（ 耗时）
	 * 
	 * @param filepath
	 *            文件的具体路径
	 * @return
	 * @throws IOException
	 *             找不到或者读流异常
	 * @method
	 */
	public static String FileToString(String filepath) throws IOException {
		InputStream in = new FileInputStream(filepath);
		byte[] bytes = new byte[in.available()];
		in.read(bytes);
		String bsStr = Base64.encodeToString(bytes, Base64.DEFAULT);
		in.close();
		return bsStr;
	}

	/**
	 * 将图片对象转换为Base64以后的字符串
	 * 
	 * @param bitmap
	 * @return
	 * @method
	 */
	public static String BitmapToString(Bitmap bitmap) {
		ByteArrayOutputStream bStream = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.PNG, 100, bStream);
		byte[] bytes = bStream.toByteArray();
		String bsStr = Base64.encodeToString(bytes, Base64.DEFAULT);
		return bsStr;
	}

	/**
	 * 获取文件后缀名
	 * 
	 * @param filepath
	 * @return
	 * @method
	 */
	public static String getFileSuffix(String filepath) {
		File file = createNewFile(filepath);
		if (file == null)
			return "";
		String fileName = file.getName();
		String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
		return prefix;
	}

	/**
	 * 判断文件是否存在
	 * 
	 * @return
	 */
	public static boolean isFileExist(String filepath) {
		return new File(filepath).exists();
	}

	/**
	 * 判断SD是否可以使用
	 * 
	 * @return
	 */
	public static boolean isSdcardExist() {
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return true;
		}
		return false;
	}

	/**
	 * 创建文件
	 * 
	 * @param path
	 *            文件路径
	 * @return 创建的文件
	 */
	public static File createNewFile(String path) {
		File file = new File(path);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				return null;
			}
		}
		return file;
	}

	/**
	 * 删除文件夹
	 * 
	 * @param folderPath
	 *            文件夹的路径
	 */
	public static void delFolder(String folderPath) {
		delAllFile(folderPath);
		String filePath = folderPath;
		filePath = filePath.toString();
		java.io.File myFilePath = new java.io.File(filePath);
		myFilePath.delete();
	}

	/**
	 * 删除文件
	 * 
	 * @param path
	 *            文件的路径
	 */
	public static void delAllFile(String path) {
		File file = new File(path);
		if (!file.exists()) {
			return;
		}
		if (!file.isDirectory()) {
			return;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);
				delFolder(path + "/" + tempList[i]);
			}
		}
	}

	/**
	 * 获取文件的Uri
	 * 
	 * @param path
	 *            文件的路径
	 * @return
	 */
	public static Uri getUriFromFile(String path) {
		File file = new File(path);
		return Uri.fromFile(file);
	}

	/**
	 * 换算文件大小
	 * 
	 * @param size
	 * @return
	 */
	public static String formatFileSize(long size) {
		DecimalFormat df = new DecimalFormat("#.00");
		String fileSizeString = "未知大小";
		if (size < 1024) {
			fileSizeString = df.format((double) size) + "B";
		} else if (size < 1048576) {
			fileSizeString = df.format((double) size / 1024) + "K";
		} else if (size < 1073741824) {
			fileSizeString = df.format((double) size / 1048576) + "M";
		} else {
			fileSizeString = df.format((double) size / 1073741824) + "G";
		}
		return fileSizeString;
	}

	/** 根据path加载图片bit **/
	public static Bitmap getBitmap(String path) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 4;//
		options.inJustDecodeBounds = false;
		Bitmap b = BitmapFactory.decodeFile(path, options);
		return b;
	}

	/** 压缩图片（耗时） **/
	public static Bitmap compressBitmap(String path, int compressSize) {
		Bitmap b = getBitmap(path);
		return compressImage(b, compressSize);
	}

	/**
	 * 压缩图片比例（依据文件路径） 再压缩图片质量返回(耗时）--过时 暂时别用
	 * 
	 * @param srcPath
	 * @param compressSize
	 * @method
	 */
	@Deprecated
	public static Bitmap compressImage(String srcPath, int compressSize) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		// 现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
		float hh = 480f;// 这里设置高度为800f
		float ww = 320f;// 这里设置宽度为480f
		// 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置缩放比例
		// 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		return compressImage(bitmap, compressSize);// 压缩好比例大小后再进行质量压缩
	}

	/**
	 * 压缩bitmap的质量（按照指定的压缩大小来处理）如果不传，默认为100kb（耗时）
	 * 
	 * @param bitmap
	 * @param compressSize
	 * @return
	 * @method
	 */
	@Deprecated
	public static Bitmap compressImage(Bitmap bitmap, int compressSize) {
		if (compressSize == 0)
			compressSize = 100;// 默认压缩100kb
		LogUtil.e("--------图片压缩------" + compressSize);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		int options = 100;
		if (baos.toByteArray().length / 1024 < compressSize) {
			LogUtil.e("当前图片<" + compressSize);
			return bitmap;
		}
		while (baos.toByteArray().length / 1024 > compressSize) { // 循环判断如果压缩后图片是否大于compressSizekb,大于继续压缩
			baos.reset();// 重置baos即清空baos
			bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
			options -= 6;// 每次都减少6
			if (options <= 0)
				break;
			LogUtil.e("baos.toByteArray().length==" + baos.toByteArray().length);
			LogUtil.e("------压缩次数-------" + options
					+ "baos.toByteArray().length / 1024=="
					+ baos.toByteArray().length / 1024);
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		LogUtil.e("------压缩结果-------" + baos.toByteArray().length / 1024);
		Bitmap bitNew = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
		return bitNew;
	}

	/**
	 * 保存图片到SD卡
	 * 
	 * @param bitmap
	 *            图片的bitmap对象
	 * @return
	 */
	public static String BitmapToFile(Bitmap bitmap, String fileTarget) {
		if (!FileUtil.isSdcardExist()) {
			LogUtil.e("sd卡不存在");
			return null;
		}
		FileOutputStream fileOutputStream = null;
		File dir = new File(fileTarget);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		String fileName = UUID.randomUUID().toString() + ".jpg";
		String newFilePath = fileTarget + fileName;
		File file = FileUtil.createNewFile(newFilePath);
		if (file == null) {
			LogUtil.e("创建文件失败");
			return null;
		}
		try {
			fileOutputStream = new FileOutputStream(newFilePath);
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
		} catch (FileNotFoundException e1) {
			LogUtil.e("文件不存在");
			return null;
		} finally {
			try {
				fileOutputStream.flush();
				fileOutputStream.close();
			} catch (IOException e) {
				return null;
			}
		}
		return newFilePath;
	}

	/** 获取sd卡根目录 **/
	public static String getSDPath() {
		if (FileUtil.isSdcardExist()) {
			return Environment.getExternalStorageDirectory().toString();
		}
		return "";
	}

	/**
	 * 通过手机照相获取图片
	 * 
	 * @param activity
	 * @return 照相后图片的路径
	 */
	public static String takePicture(BaseActivity activity, String fileTarget) {
		File dir = new File(fileTarget);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		String path = fileTarget + UUID.randomUUID().toString() + ".jpg";
		File file = FileUtil.createNewFile(path);
		if (file != null) {
			intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
		}
		activity.startActivityForResult(intent, 1);
		return path;
	}

	/** 创建文件夹 **/
	public static void mkDirs(String fileDir) {
		File dir = new File(fileDir);
		if (!dir.exists())
			dir.mkdirs();
	}

	/**
	 * 解压缩
	 * 
	 * @param zipFile
	 *            zip的路径
	 * @param location
	 *            目标目录
	 * @throws IOException
	 *             io异常需要抓取
	 */
	public static void unzip(String zipFile, String location)
			throws IOException {
		int size;
		byte[] buffer = new byte[BUFFER_SIZE];

		try {
			if (!location.endsWith("/")) {
				location += "/";
			}
			File f = new File(location);
			if (!f.isDirectory()) {
				f.mkdirs();
			}
			ZipInputStream zin = new ZipInputStream(new BufferedInputStream(
					new FileInputStream(zipFile), BUFFER_SIZE));
			try {
				ZipEntry ze = null;
				while ((ze = zin.getNextEntry()) != null) {
					String path = location + ze.getName();
					File unzipFile = new File(path);

					if (ze.isDirectory()) {
						if (!unzipFile.isDirectory()) {
							unzipFile.mkdirs();
						}
					} else {
						File parentDir = unzipFile.getParentFile();
						if (null != parentDir) {
							if (!parentDir.isDirectory()) {
								parentDir.mkdirs();
							}
						}

						FileOutputStream out = new FileOutputStream(unzipFile,
								false);
						BufferedOutputStream fout = new BufferedOutputStream(
								out, BUFFER_SIZE);
						try {
							while ((size = zin.read(buffer, 0, BUFFER_SIZE)) != -1) {
								fout.write(buffer, 0, size);
							}

							zin.closeEntry();
						} finally {
							fout.flush();
							fout.close();
						}
					}
				}
			} finally {
				zin.close();
			}
		} catch (Exception e) {
			LogUtil.e("" + e.toString());
		}
	}

}
